package com.desaysv.svview

import android.animation.Animator
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.TypedArray
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.widget.FrameLayout
import android.widget.RelativeLayout
import com.desaysv.svview.databinding.LayoutProgressBinding

@SuppressLint("CustomViewStyleable")
class ProgressBar @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attributeSet, defStyleAttr) {
    companion object {
        private const val TAG = "ProgressBar"
    }

    private val binding = LayoutProgressBinding.inflate(LayoutInflater.from(context))

    private var background = -1
    private var progressBackground = -1
    private var backgroundColor = -1
    private var progressBackgroundColor = -1

    private var progressMax = 100
    private var progress = 10

    private var animatorDuring = 100
    private var progressBackgroundMargin = -1


    private var mainRadius = 0f

    private var canSeek=false


    init {
        attributeSet?.let {
            val typedArray: TypedArray =
                context.obtainStyledAttributes(it, R.styleable.ProgressBar)

            background = typedArray.getResourceId(R.styleable.ProgressBar_background, -1)
            progressBackground =
                typedArray.getResourceId(R.styleable.ProgressBar_progressBackground, -1)
            backgroundColor = typedArray.getColor(
                R.styleable.ProgressBar_backgroundColor,
                Color.parseColor("#dddddd")
            )
            progressBackgroundColor = typedArray.getColor(
                R.styleable.ProgressBar_progressBackgroundColor,
                Color.parseColor("#ff55ff")
            )

            progressMax = typedArray.getInt(R.styleable.ProgressBar_progressMax, 100)
            progress = typedArray.getInt(R.styleable.ProgressBar_progress, 10)
            progressBackgroundMargin = typedArray.getDimensionPixelSize(
                R.styleable.ProgressBar_progressBackgroundMargin,
                -1
            )
            mainRadius = typedArray.getDimensionPixelSize(R.styleable.ProgressBar_containerRadius, 0).toFloat()
            canSeek= typedArray.getBoolean(R.styleable.ProgressBar_seek, false)

            typedArray.recycle()
        }

        val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        addView(binding.root, layoutParams)
    }

    private var width = 0
    private var height = 0

    fun setProgress(progress: Int) {
        val oldProgress = if (progress < 0) {
            0
        } else if (progress > progressMax) {
            progressMax
        } else {
            progress
        }
        progressChange(oldProgress)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //测量控件的真实高度
        val width = MeasureSpec.getSize(widthMeasureSpec)
        val height = MeasureSpec.getSize(heightMeasureSpec)
        if (width == 0 || height == 0) {
            return
        }
        if (width == this.width && height == this.height) {
            return
        }
        this.width = width
        this.height = height
        Log.i(TAG, "onMeasure: width=$width , height=$height")
        if (progressBackgroundMargin == -1) {
            progressBackgroundMargin = (height * 0.1).toInt()
        }
        resize()
    }

    private val screentLocation = IntArray(2)
    override fun dispatchTouchEvent(event: MotionEvent): Boolean {
        if(!canSeek){
            return super.dispatchTouchEvent(event)
        }
        var oldProgress = progress
        if (event.action == MotionEvent.ACTION_DOWN) {
            val rawX = event.rawX
            this.getLocationOnScreen(screentLocation)
            val holpX = rawX - screentLocation[0]
            var holpPrecent = holpX / width
            if (holpPrecent < 0) {
                holpPrecent = 0f
            } else if (holpPrecent > 1) {
                holpPrecent = 1f
            }
            oldProgress = (progressMax * holpPrecent).toInt()
        }
        if (event.action == MotionEvent.ACTION_MOVE) {
            val rawX = event.rawX
            val holpX = rawX - screentLocation[0]
            var holpPrecent = holpX / width
            if (holpPrecent < 0) {
                holpPrecent = 0f
            } else if (holpPrecent > 1) {
                holpPrecent = 1f
            }
            oldProgress = (progressMax * holpPrecent).toInt()
        }
        if (event.action == MotionEvent.ACTION_UP) {
            val rawX = event.rawX
            val holpX = rawX - screentLocation[0]
            var holpPrecent = holpX / width
            if (holpPrecent < 0) {
                holpPrecent = 0f
            } else if (holpPrecent > 1) {
                holpPrecent = 1f
            }
            oldProgress = (progressMax * holpPrecent).toInt()
        }
        this.post {
            selectBgAnimator?.cancel()
            progressChange(oldProgress, false)
        }
        return true
    }

    private fun resize() {
        Log.i(TAG, "resize: ")
        //先配置背景
        setCornerRadius(height.toFloat())
        progressChange(progress, false)
    }

    private var selectBgAnimator: Animator? = null

    interface OnProgressChangeListener {
        fun onProgressChange(progress: Int, progressMax: Int)
    }

    private var onProgressChangeListener: OnProgressChangeListener? = null
    fun setOnProgressChangeListener(listener: OnProgressChangeListener?) {
        onProgressChangeListener = listener
    }

    private fun progressChange(newProgress: Int, withAnimator: Boolean = true) {
        val needCallback = progress != newProgress
        progress = newProgress
        val percent = progress.toFloat() / progressMax
        var progressBarWidth = 0
        if (progress > 0) {
            progressBarWidth = (width * percent).toInt()
        }
        val currentWidth = binding.ivProgressBg.layoutParams.width
        if (!withAnimator) {
            binding.ivProgressBg.layoutParams.width = progressBarWidth
            binding.ivProgressBg.requestLayout()
            if (!needCallback) {
                return
            }
            onProgressChangeListener?.onProgressChange(progress, progressMax)
            return
        }
        selectBgAnimator?.cancel()
        selectBgAnimator = ValueAnimator.ofInt(currentWidth, progressBarWidth).apply {
            duration = animatorDuring.toLong()
            addUpdateListener {
                binding.ivProgressBg.layoutParams.width = it.animatedValue as Int
                binding.ivProgressBg.requestLayout()
            }
            addListener(object : Animator.AnimatorListener {
                override fun onAnimationStart(animation: Animator) {
                    if (!needCallback) {
                        return
                    }
                    onProgressChangeListener?.onProgressChange(progress, progressMax)
                }

                override fun onAnimationEnd(animation: Animator) {

                }

                override fun onAnimationCancel(animation: Animator) {
                }

                override fun onAnimationRepeat(animation: Animator) {
                }

            })
            start()
        }
    }

    // 添加设置圆角的方法
    private fun setCornerRadius(radius: Float) {
        Log.i(TAG, "setCornerRadius: ")
        if (background != -1) {
            binding.ivDefaultBg.setBackgroundResource(background)
        }
        if (progressBackground != -1) {
            binding.ivProgressBg.setBackgroundResource(progressBackground)
        }

        if (background == -1) {
            // 修改默认背景的圆角
            val defaultBackground = GradientDrawable().apply {
                setColor(backgroundColor)
                shape = GradientDrawable.RECTANGLE
                cornerRadius = radius
            }
            binding.ivDefaultBg.background = defaultBackground
        }
        if (progressBackground == -1) {
            // 修改选中背景的圆角
            val selectedBackground = GradientDrawable().apply {
                setColor(progressBackgroundColor)
                shape = GradientDrawable.RECTANGLE
                cornerRadius = radius
            }
            binding.ivProgressBg.background = selectedBackground
        }
        (binding.cdProgress.layoutParams as RelativeLayout.LayoutParams).setMargins(
            progressBackgroundMargin,
            progressBackgroundMargin,
            progressBackgroundMargin,
            progressBackgroundMargin
        )

        val mainBg = binding.ivDefaultBg.background
        if (mainBg is GradientDrawable) {
            val radius = mainBg.cornerRadius
            if(mainRadius==0f){
                mainRadius=radius
            }
            Log.i(TAG, "setCornerRadius: $mainRadius")
            binding.root.radius = mainRadius
            binding.root.requestLayout()

            if(progressBackgroundMargin!=-1){
                binding.cdProgress.radius=mainRadius-progressBackgroundMargin.toFloat()
                binding.cdProgress.requestLayout()
            }
        }
    }

    fun setContainerRadius(radius: Float) {
        mainRadius = radius
        binding.root.radius = mainRadius
        binding.root.requestLayout()
        if(progressBackgroundMargin!=-1){
            binding.cdProgress.radius=mainRadius-progressBackgroundMargin.toFloat()
            binding.cdProgress.requestLayout()
        }
    }
}